<template>
  <div class="editor-container">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <el-button type="primary" @click="showPreview = true" :disabled="pageComponents.length === 0">
        <el-icon><View /></el-icon>
        预览页面
      </el-button>
      <el-button @click="clearCanvas">
        <el-icon><Delete /></el-icon>
        清空画布
      </el-button>
      <div class="toolbar-right">
        <el-checkbox v-model="snapToGrid">对齐网格</el-checkbox>
        <el-checkbox v-model="showGrid">显示网格</el-checkbox>
      </div>
    </div>

    <div class="editor-content">
      <!-- 组件库区域 -->
      <el-card class="component-palette" shadow="never">
        <template #header>
          <div class="card-header">
            <span>组件库</span>
          </div>
        </template>
        <div class="component-list">
          <div
              v-for="(comp, index) in componentTypes"
              :key="index"
              draggable="true"
              @dragstart="handleDragStart($event, comp.type)"
              class="component-item"
          >
            <el-icon class="component-icon">
              <component :is="comp.icon" />
            </el-icon>
            <span>{{ comp.label }}</span>
          </div>
        </div>
      </el-card>

      <!-- 画布区域 -->
      <el-card class="canvas-area-container" shadow="never">
        <template #header>
          <div class="card-header">
            <span>画布区域</span>
            <el-text type="info" size="small">
              已添加 {{ pageComponents.length }} 个组件
            </el-text>
          </div>
        </template>
        <div
            class="canvas-area"
            @dragover="handleDragOver"
            @drop="handleDrop"
            ref="canvasArea"
        >
          <!-- 8x8网格线 -->
          <div class="grid-overlay" v-if="showGrid">
            <div
                v-for="col in gridColumns + 1"
                :key="'v-'+col"
                class="grid-line vertical"
                :style="{ left: (col - 1) * (100 / gridColumns) + '%' }"
            ></div>
            <div
                v-for="row in gridRows + 1"
                :key="'h-'+row"
                class="grid-line horizontal"
                :style="{ top: (row - 1) * (100 / gridRows) + '%' }"
            ></div>
          </div>

          <div
              v-for="(item, index) in pageComponents"
              :key="item.id"
              class="canvas-component"
              :class="{ 'selected': selectedComponentIndex === index }"
              :style="{
              left: item.x + 'px',
              top: item.y + 'px',
              width: item.width ? item.width + 'px' : 'auto',
              height: item.height ? item.height + 'px' : 'auto'
            }"
              @mousedown="startDrag(index, $event)"
          >
            <component
                :is="getComponent(item.type)"
                :config="item.config"
                :editable="true"
            />
            <div class="component-actions">
              <el-button
                  circle
                  size="small"
                  type="danger"
                  @click.stop="removeComponent(index)"
                  class="delete-btn"
              >
                <el-icon><Delete /></el-icon>
              </el-button>
            </div>
          </div>

          <div v-if="pageComponents.length === 0" class="empty-canvas">
            <el-empty description="从左侧拖拽组件到此处开始设计" :image-size="200" />
          </div>
        </div>
      </el-card>

      <!-- 属性面板 -->
      <el-card class="property-panel" shadow="never" v-if="selectedComponent">
        <template #header>
          <div class="card-header">
            <span>组件属性</span>
            <el-tag type="primary" size="small">
              {{ getComponentLabel(selectedComponent.type) }}
            </el-tag>
          </div>
        </template>

        <el-form :model="selectedComponent.config" label-width="80px" label-position="left">
          <el-form-item
              v-for="(prop, key) in getEditableProps(selectedComponent.type)"
              :key="key"
              :label="prop.label"
          >
            <el-input
                v-if="prop.type === 'text'"
                v-model="selectedComponent.config[key]"
                :placeholder="`请输入${prop.label}`"
            />
            <el-color-picker
                v-else-if="prop.type === 'color'"
                v-model="selectedComponent.config[key]"
                show-alpha
            />
            <el-input-number
                v-else-if="prop.type === 'number'"
                v-model="selectedComponent.config[key]"
                :min="prop.min || 0"
                :max="prop.max || 1000"
            />
          </el-form-item>

          <el-divider />

          <el-form-item label="位置">
            <div class="position-controls">
              <el-input-number
                  v-model="selectedComponent.x"
                  label="X"
                  :min="0"
                  :max="canvasSize.width"
                  size="small"
              />
              <el-input-number
                  v-model="selectedComponent.y"
                  label="Y"
                  :min="0"
                  :max="canvasSize.height"
                  size="small"
              />
            </div>
          </el-form-item>

          <el-form-item label="尺寸">
            <div class="size-controls">
              <el-input-number
                  v-model="selectedComponent.width"
                  label="宽度"
                  :min="50"
                  :max="800"
                  size="small"
              />
              <el-input-number
                  v-model="selectedComponent.height"
                  label="高度"
                  :min="30"
                  :max="600"
                  size="small"
              />
            </div>
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 预览模态框 -->
    <el-dialog
        v-model="showPreview"
        title="页面预览"
        width="80%"
        top="5vh"
        destroy-on-close
        class="preview-dialog"
    >
      <div class="preview-container">
        <div
            v-for="(item, index) in pageComponents"
            :key="index"
            class="preview-component"
            :style="{
            left: item.x + 'px',
            top: item.y + 'px',
            width: item.width ? item.width + 'px' : 'auto',
            height: item.height ? item.height + 'px' : 'auto'
          }"
        >
          <component
              :is="getComponent(item.type)"
              :config="item.config"
              :editable="false"
              @button-click="handleButtonClick"
              @input-change="handleInputChange"
          />
        </div>
      </div>

      <template #footer>
        <el-button @click="showPreview = false">关闭预览</el-button>
        <el-button type="primary" @click="handlePreviewSubmit">提交表单</el-button>
      </template>
    </el-dialog>

    <!-- 预览操作提示 -->
    <el-dialog
        v-model="showActionDialog"
        title="操作结果"
        width="400px"
        center
    >
      <div style="text-align: center; padding: 20px;">
        <el-icon size="48" color="#67C23A" v-if="actionType === 'success'">
          <SuccessFilled />
        </el-icon>
        <el-icon size="48" color="#E6A23C" v-else-if="actionType === 'warning'">
          <Warning />
        </el-icon>
        <el-icon size="48" color="#F56C6C" v-else>
          <InfoFilled />
        </el-icon>
        <div style="margin-top: 16px; font-size: 16px;">{{ actionMessage }}</div>
      </div>
      <template #footer>
        <el-button type="primary" @click="showActionDialog = false">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
/* eslint-disable */
import { ref, computed, onMounted, onUnmounted } from 'vue'
import {
  View,
  Delete,
  Edit,
  Picture,
  Document,
  Star,
  SuccessFilled,
  Warning,
  InfoFilled
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

import TextComponent   from "@/components/TextComponent.vue";
import InputComponent  from "@/components/InputComponent.vue";
import ImageComponent from "@/components/ImageComponent.vue";
import ButtonComponent from "@/components/ButtonComponent.vue";
import TEditorComponent from "@/components/TEditorComponent.vue";

// 组件映射
const componentMap = {
  'text': TextComponent,
  'image': ImageComponent,
  'button': ButtonComponent,
  'input': InputComponent,
  'editor': TEditorComponent
}

// 可用组件类型
const componentTypes = [
  { type: 'text', label: '文本组件', icon: Document },
  { type: 'image', label: '图片组件', icon: Picture },
  { type: 'button', label: '按钮组件', icon: Star },
  { type: 'input', label: '输入框', icon: Edit },
  { type: 'editor', label: '富文本组件', icon: Edit }
]

// 页面组件数据
const pageComponents = ref([])
const selectedComponentIndex = ref(null)
const dragOffset = ref({ x: 0, y: 0 })
const showGrid = ref(true)
const snapToGrid = ref(true)
const gridColumns = ref(8)
const gridRows = ref(8)
const canvasArea = ref(null)
const showPreview = ref(false)
const canvasSize = ref({ width: 800, height: 600 })
const showActionDialog = ref(false)
const actionMessage = ref('')
const actionType = ref('info')
const formData = ref({})

// 当前选中组件
const selectedComponent = computed(() => {
  return selectedComponentIndex.value !== null
      ? pageComponents.value[selectedComponentIndex.value]
      : null
})

// 可编辑属性配置
const editableProps = {
  text: {
    text: { label: '文本内容', type: 'text' },
    color: { label: '颜色', type: 'color' },
    fontSize: { label: '字体大小', type: 'number', min: 12, max: 72 }
  },
  image: {
    src: { label: '图片URL', type: 'text' },
    alt: { label: '替代文本', type: 'text' }
  },
  button: {
    text: { label: '按钮文本', type: 'text' },
    color: { label: '背景颜色', type: 'color' },
    fontSize: { label: '字体大小', type: 'number', min: 12, max: 24 }
  },
  input: {
    label: { label: '标签文本', type: 'text' },
    placeholder: { label: '占位文本', type: 'text' },
    fieldName: { label: '字段名', type: 'text' }
  },
  editor: {
    placeholder: { label: '占位文本', type: 'text' },
    fieldName: { label: '字段名', type: 'text' }
  }
}

// 获取组件实例
const getComponent = (type) => {
  return componentMap[type] || TextComponent
}

// 获取组件显示标签
const getComponentLabel = (type) => {
  const comp = componentTypes.find(c => c.type === type)
  return comp ? comp.label : '未知组件'
}

// 获取可编辑属性
const getEditableProps = (type) => {
  return editableProps[type] || {}
}

// 拖拽开始处理
const handleDragStart = (e, type) => {
  e.dataTransfer.setData('component-type', type)
}

// 拖拽经过处理
const handleDragOver = (e) => {
  e.preventDefault()
}

// 获取网格单元宽度和高度（像素）
const getGridCellSize = (containerWidth, containerHeight) => {
  return {
    width: containerWidth / gridColumns.value,
    height: containerHeight / gridRows.value
  }
}

// 对齐到网格
const snapToGridPosition = (x, y, containerWidth, containerHeight) => {
  if (snapToGrid.value) {
    const cellSize = getGridCellSize(containerWidth, containerHeight)
    const snappedX = Math.round(x / cellSize.width) * cellSize.width
    const snappedY = Math.round(y / cellSize.height) * cellSize.height
    return { x: snappedX, y: snappedY }
  }
  return { x, y }
}

// 放置处理
const handleDrop = (e) => {
  e.preventDefault()
  const type = e.dataTransfer.getData('component-type')
  if (!type) return

  const rect = e.currentTarget.getBoundingClientRect()
  const containerWidth = rect.width
  const containerHeight = rect.height

  // 计算放置位置
  let x = e.clientX - rect.left
  let y = e.clientY - rect.top

  // 对齐到网格
  const snapped = snapToGridPosition(x, y, containerWidth, containerHeight)
  x = snapped.x
  y = snapped.y

  const newComponent = {
    id: Date.now(),
    type: type,
    x: x,
    y: y,
    width: getDefaultSize(type).width,
    height: getDefaultSize(type).height,
    config: getDefaultConfig(type)
  }

  pageComponents.value.push(newComponent)
  selectedComponentIndex.value = pageComponents.value.length - 1
}

// 开始拖动画布上的组件
const startDrag = (index, e) => {
  selectedComponentIndex.value = index
  const component = pageComponents.value[index]
  dragOffset.value = {
    x: e.clientX - component.x,
    y: e.clientY - component.y
  }

  const moveHandler = (moveEvent) => {
    const container = canvasArea.value
    const rect = container ? container.getBoundingClientRect() : { width: window.innerWidth, height: window.innerHeight }
    const containerWidth = rect.width
    const containerHeight = rect.height

    let newX = moveEvent.clientX - dragOffset.value.x
    let newY = moveEvent.clientY - dragOffset.value.y

    // 对齐到网格
    const snapped = snapToGridPosition(newX, newY, containerWidth, containerHeight)
    newX = snapped.x
    newY = snapped.y

    component.x = newX
    component.y = newY
  }

  const upHandler = () => {
    document.removeEventListener('mousemove', moveHandler)
    document.removeEventListener('mouseup', upHandler)
  }

  document.addEventListener('mousemove', moveHandler)
  document.addEventListener('mouseup', upHandler)
}

// 删除组件
const removeComponent = (index) => {
  pageComponents.value.splice(index, 1)
  if (selectedComponentIndex.value === index) {
    selectedComponentIndex.value = null
  }
}

// 清空画布
const clearCanvas = () => {
  pageComponents.value = []
  selectedComponentIndex.value = null
}

// 获取组件默认配置
const getDefaultConfig = (type) => {
  const configs = {
    text: { text: '默认文本', color: '#000000', fontSize: 16 },
    image: { src: 'https://picsum.photos/200/150', alt: '示例图片' },
    button: { text: '点击按钮', color: '#409EFF', fontSize: 14 },
    input: { label: '输入框', placeholder: '请输入内容', fieldName: 'input_' + Date.now() },
    editor: { placeholder: '请输入内容', fieldName: 'editor_' + Date.now() }
  }
  return { ...configs[type] }
}

// 获取组件默认尺寸
const getDefaultSize = (type) => {
  const sizes = {
    text: { width: 120, height: 40 },
    image: { width: 200, height: 150 },
    button: { width: 100, height: 40 },
    input: { width: 200, height: 40 },
    editor: { width: 600, height: 400 }
  }
  return { ...sizes[type] }
}

// 处理按钮点击事件
const handleButtonClick = (config) => {
  actionMessage.value = `按钮 "${config.text}" 被点击了！`
  actionType.value = 'success'
  showActionDialog.value = true
  ElMessage.success(`按钮 "${config.text}" 点击成功`)
}

// 处理输入框变化事件
const handleInputChange = (value, config) => {
  const fieldName = config.fieldName || 'unknown'
  formData.value[fieldName] = value
  console.log(`输入框 "${config.label}" 值变为:`, value)
}

// 处理预览表单提交
const handlePreviewSubmit = () => {
  const inputComponents = pageComponents.value.filter(comp => comp.type === 'input')

  if (inputComponents.length === 0) {
    actionMessage.value = '当前没有可提交的输入框组件'
    actionType.value = 'warning'
    showActionDialog.value = true
    return
  }

  // 收集所有输入框数据
  const formData = {}
  inputComponents.forEach(comp => {
    const fieldName = comp.config.fieldName || `input_${comp.id}`
    formData[fieldName] = comp.config.value || ''
  })

  actionMessage.value = `表单提交成功！数据：${JSON.stringify(formData, null, 2)}`
  actionType.value = 'success'
  showActionDialog.value = true

  ElMessage.success('表单提交成功！')
  console.log('表单数据:', formData)
}
</script>

<style scoped>
.editor-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
}

.toolbar {
  padding: 15px 20px;
  background: white;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  gap: 10px;
}

.toolbar-right {
  margin-left: auto;
  display: flex;
  gap: 15px;
}

.editor-content {
  flex: 1;
  display: flex;
  gap: 16px;
  padding: 16px;
  overflow: hidden;
}

.component-palette {
  width: 280px;
  flex-shrink: 0;
}

.component-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.component-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border: 1px dashed #dcdfe6;
  border-radius: 4px;
  cursor: move;
  transition: all 0.3s;
  background: white;
}

.component-item:hover {
  border-color: #409eff;
  background: #f0f7ff;
}

.component-icon {
  color: #409eff;
}

.canvas-area-container {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.canvas-area {
  flex: 1;
  position: relative;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: hidden;
  min-height: 500px;
}

/* 网格覆盖层 */
.grid-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
}

.grid-line {
  position: absolute;
}

.grid-line.vertical {
  top: 0;
  bottom: 0;
  width: 1px;
  border-left: 1px dashed #e4e7ed;
}

.grid-line.horizontal {
  left: 0;
  right: 0;
  height: 1px;
  border-top: 1px dashed #e4e7ed;
}

.canvas-component {
  position: absolute;
  cursor: move;
  border: 2px solid transparent;
  border-radius: 4px;
  background: white;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
  padding: 4px;
}

.canvas-component:hover {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}

.canvas-component.selected {
  border-color: #409eff;
  box-shadow: 0 2px 12px rgba(64, 158, 255, 0.3);
}

.component-actions {
  position: absolute;
  top: -12px;
  right: -12px;
  opacity: 0;
  transition: opacity 0.3s;
}

.canvas-component:hover .component-actions {
  opacity: 1;
}

.empty-canvas {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.property-panel {
  width: 320px;
  flex-shrink: 0;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.position-controls,
.size-controls {
  display: flex;
  gap: 8px;
}

.position-controls .el-input-number,
.size-controls .el-input-number {
  flex: 1;
}

.preview-container {
  position: relative;
  min-height: 500px;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: auto;
  padding: 20px;
}

.preview-component {
  position: absolute;
}

/* 预览对话框样式 */
.preview-dialog .el-dialog__body {
  padding: 0;
}

.preview-dialog .preview-container {
  min-height: 60vh;
  max-height: 70vh;
  overflow: auto;
}
</style>
